001    /* $RCSfile: DESede3KeySpec.java,v $
002     * $Revision: 1.8 $
003     * $Date: 2002/11/23 11:09:57 $
004     * $Author: uwe_guenther $
005     * $State: Exp $
006     *
007     * Created on August 11, 2001 11:18 AM
008     *
009     * Copyright (C) 2001 Uwe Guenther <uwe@cscc.de>
010     *
011     * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
012     * ServiceProvider is a library, written in JavaTM, that should be 
013     * used in HBCI banking applications (clients and may be servers),
014     * to do cryptographic operations.
015     *
016     * The jhbci library is free software; you can redistribute it and/or
017     * modify it under the terms of the GNU Lesser General Public
018     * License as published by the Free Software Foundation; either
019     * version 2.1 of the License, or (at your option) any later version.
020     *
021     * The jhbci library is distributed in the hope that it will be useful,
022     * but WITHOUT ANY WARRANTY; without even the implied warranty of
023     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
024     * Lesser General Public License for more details.
025     *
026     * You should have received a copy of the GNU Lesser General Public
027     * License along with this library; if not, write to the Free Software
028     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
029     *
030     */
031    
032    package de.cscc.crypto.provider.spec;
033    
034    import java.security.InvalidKeyException;
035    
036    /** 
037     * 3 Key Triple DES secret keys specification (168 bit or 192 bit with parity)
038     * class.
039     *
040     * <p>This class is immutable.
041     *
042     * @author  <a href=mailto:uwe@cscc.de>Uwe Günther</a>
043     * @version $Revision: 1.8 $
044     */
045    public class DESede3KeySpec implements DESKeySpec, Cloneable {
046    
047        /** Key length in bytes. */        
048        private static final int DES_EDE_3KEY_LEN = 24;
049    
050        /** Internal data representation of key1. */    
051        private DES1KeySpec key1;
052        
053        /** Internal data representation of key2. */        
054        private DES1KeySpec key2;
055    
056        /** Internal data representation of key3. */        
057        private DES1KeySpec key3;    
058        
059        /** 
060         * Creates a new DESede3KeySpec from a 24 bytes long byte array.
061         * We use the first 24 bytes in key as the key material for the DES key.
062         *
063         * The first (leftmost) DES key (key[0] to key[7]) is key1,
064         * the second (middle) DES key (key[8] to key[15]) is key2 and
065         * the third (rightmost) DES key (key[16] to key[13]) is key3.
066         *
067         * @param key the buffer with the three DES keys.
068         * @throws InvalidKeyException if the given key material is shorter
069         *                              than 24 bytes or the key is weak or semi weak.
070         */
071        public DESede3KeySpec(byte[] key) throws InvalidKeyException {
072            this(key, 0);
073        }
074        
075        /** 
076         * Creates a new DESede3KeySpec from a 24 bytes long byte array. 
077         *
078         * @param key the buffer with the DES keys.
079         * @param offset the offset in key, where the key starts.
080         * @throws InvalidKeyException if the given key material is shorter
081         *                              than 24 bytes or the key is weak or semi weak.
082         */
083        public DESede3KeySpec(byte[] key, int offset) throws InvalidKeyException {   
084            this.key1 = new DES1KeySpec(key, offset+0);
085            this.key2 = new DES1KeySpec(key, offset+8);
086            this.key3 = new DES1KeySpec(key, offset+16);        
087        }
088    
089        /** 
090         * Creates a new DESede3KeySpec from an existing one.
091         *
092         * @param key DesKeySpec object with a key.
093         */
094        public DESede3KeySpec(DESede3KeySpec key) { 
095            this.key1 = new DES1KeySpec(key.key1);
096            this.key2 = new DES1KeySpec(key.key2);
097            this.key3 = new DES1KeySpec(key.key3);
098        } 
099    
100        /** 
101         * Creates and returns a deep copy of this object.
102         *
103         * @return a clone of this instance.
104         * @see java.lang.Cloneable
105         * @exception CloneNotSupportedException if the object's class does not
106         *             support the <code>Cloneable</code> interface. Subclasses
107         *             that override the <code>clone</code> method can also
108         *             throw this exception to indicate that an instance cannot
109         *             be cloned.
110         */        
111        public Object clone() throws CloneNotSupportedException {
112           DESede3KeySpec result = (DESede3KeySpec) super.clone();
113           result.key1 = (DES1KeySpec) this.key1.clone();
114           result.key2 = (DES1KeySpec) this.key2.clone();
115           result.key3 = (DES1KeySpec) this.key3.clone();
116           return result;
117        }
118            
119        /** 
120         * Indicates whether some other object is "equal to" this one.
121         *
122         * @param   obj   the reference object with which to compare.
123         * @return  <code>true</code> if this object is the same as the obj
124         *         argument; <code>false</code> otherwise.
125         * @see     #hashCode()
126         * @see     java.util.Hashtable
127         */        
128        public boolean equals(Object obj) {
129            //Only for performance.
130            if (this == obj) {
131                return true;
132            } 
133            
134            //If obj == null then instanceof returns false, see JLS 15.20.2
135            if (!(obj instanceof DESede3KeySpec)) {
136                return false;
137            }
138            
139            DESede3KeySpec other = (DESede3KeySpec)obj;
140            return this.key1.equals(other.key1) &&
141                   this.key2.equals(other.key2) &&
142                   this.key3.equals(other.key3)  ;
143        }
144        
145        /**
146         * Returns a hash code value for the object. This method is
147         * supported for the benefit of hashtables such as those provided by
148         * <code>java.util.Hashtable</code>.
149         *
150         * @return  a hash code value for this object.
151         * @see     #equals(java.lang.Object)
152         * @see     java.util.Hashtable
153         */    
154        public int hashCode() {
155            int result = 17;
156            result = 37*result + this.key1.hashCode();
157            result = 37*result + this.key2.hashCode();
158            result = 37*result + this.key3.hashCode();
159            return result;
160        }    
161    
162        /** 
163         * Returns a string representation of the object. 
164         * The Format may catch (change in further releases.
165         *
166         * @return  a string representation of the object.
167         */     
168        public String toString() {    
169            return "key1: [" + this.key1 + "] " +
170                   "key2: [" + this.key2 + "] " +
171                   "key3: [" + this.key3 + "]";
172        }
173    
174        /** 
175         * Get the DES Key as byte[24].
176         *
177         * @return the DES Key as byte[24]. 
178         */    
179        public byte[] getKey() {
180            byte[] returnValue = new byte[24];
181            System.arraycopy(this.key1.getKey(), 0, returnValue, 0, 8);
182            System.arraycopy(this.key2.getKey(), 0, returnValue, 8, 8);
183            System.arraycopy(this.key3.getKey(), 0, returnValue, 16, 8);
184            return returnValue;
185        }
186    }